home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
scheme
/
boxer
/
boxer.lha
/
emanip.lisp
< prev
next >
Wrap
Text File
|
1993-07-17
|
25KB
|
749 lines
;; -*- Mode:LISP; Package:(BOXER GLOBAL 1000); Base:10.; Fonts:CPTFONT -*-
;;; (C) Copyright 1985 Massachusetts Institute of Technology
;;;
;;; Permission to use, copy, modify, distribute, and sell this software
;;; and its documentation for any purpose is hereby granted without fee,
;;; provided that the above copyright notice appear in all copies and that
;;; both that copyright notice and this permission notice appear in
;;; supporting documentation, and that the name of M.I.T. not be used in
;;; advertising or publicity pertaining to distribution of the software
;;; without specific, written prior permission. M.I.T. makes no
;;; representations about the suitability of this software for any
;;; purpose. It is provided "as is" without express or implied warranty.
;;;
;;;;Primitive box manipulation.
;;This file defines the interface to the internal boxer data structure.
;;The functions in this file should be use as an interface between the
;;internal editor data structure and the world.
;;;; LABEL-PAIRs, NAME-PAIRs, and the concept of ROW-ENTRIES
(DEFCONST *INPUTS-CODE* #/)
(DEFCONST *LABELLING-CODE* #/:)
(defconst *accessing-code* #/)
;;; excls and atsigns
(DEFVAR *UNBOX-MARKER* 'UNBOX-IT)
(DEFVAR *EVAL-MARKER* 'EVAL-IT)
(DEFUN MAKE-LABEL-PAIR (LABEL ELEMENT)
`(:LABEL-PAIR ,LABEL . ,ELEMENT))
(DEFSUBST LABEL-PAIR? (X)
(AND (LISTP X)
(EQ (CAR X) ':LABEL-PAIR)))
(DEFSUBST LABEL-PAIR-LABEL (LABEL-PAIR)
(CADR LABEL-PAIR))
(DEFSUBST LABEL-PAIR-ELEMENT (LABEL-PAIR)
(CDDR LABEL-PAIR))
(DEFPROP :LABEL-PAIR MAKE-LABEL-PAIR-STREAM :MAKE-BOXER-STREAM)
(DEFUN MAKE-LABEL-PAIR-STREAM (LABEL-PAIR)
(MAKE-PDL-STREAM `(,(FORMAT NIL "~A" (LABEL-PAIR-LABEL LABEL-PAIR))
,*LABELLING-CODE*
,(IF (EQ :NO-ELEMENT (LABEL-PAIR-ELEMENT LABEL-PAIR))
""
(FORMAT NIL "~A" (LABEL-PAIR-ELEMENT LABEL-PAIR))))))
;;; Atsigns at top level and inside of builds
(DEFUN MAKE-UNBOX-TOKEN (UNBOX-TYPE BOX)
(LIST UNBOX-TYPE BOX))
(DEFSUBST UNBOX-TOKEN? (X)
(AND (LISTP X)
(EQ (CAR X) *UNBOX-MARKER*)))
(DEFSUBST UNBOX-TOKEN-TYPE (UNBOX-TOKEN)
(CAR UNBOX-TOKEN))
(DEFSUBST UNBOX-TOKEN-ELEMENT (UNBOX-TOKEN)
(CADR UNBOX-TOKEN))
(PUTPROP *UNBOX-MARKER* 'MAKE-UNBOX-TOKEN-STREAM :MAKE-BOXER-STREAM)
(DEFUN MAKE-UNBOX-TOKEN-STREAM (UT)
(MAKE-PDL-STREAM `(@ ,(IF (BOX? (UNBOX-TOKEN-ELEMENT UT))
(MAKE-BOX-STREAM (UNBOX-TOKEN-ELEMENT UT))
(FORMAT NIL "~A" (UNBOX-TOKEN-ELEMENT UT))))))
;;; Excls inside of BUILDs
(DEFUN MAKE-EVAL-IT-TOKEN (THING)
(LIST *EVAL-MARKER* THING))
(DEFSUBST EVAL-IT-TOKEN? (X)
(AND (LISTP X)
(EQ (CAR X) *EVAL-MARKER*)))
(DEFSUBST EVAL-IT-TOKEN-ELEMENT (ET)
(CADR ET))
(PUTPROP *EVAL-MARKER* 'MAKE-EVAL-IT-TOKEN-STREAM :MAKE-BOXER-STREAM)
(DEFUN MAKE-EVAL-IT-TOKEN-STREAM (ET)
(MAKE-PDL-STREAM `(! ,(IF (BOX? (EVAL-IT-TOKEN-ELEMENT ET))
(MAKE-BOX-STREAM (EVAL-IT-TOKEN-ELEMENT ET))
(FORMAT NIL "~A" (EVAL-IT-TOKEN-ELEMENT ET))))))
(defun make-access-pair (superbox subbox)
`(:access-pair ,superbox . ,subbox))
(defsubst access-pair? (x)
(and (listp x)(eq (car x) ':access-pair)))
(defsubst access-pair-superbox (access-pair)(cadr access-pair))
(defsubst access-pair-subbox (access-pair)(cddr access-pair))
(defprop :access-pair make-access-pair-stream :make-boxer-stream)
(defun make-access-pair-stream (access-pair)
(make-pdl-stream `('(format nil "~A" (access-pair-superbox access-pair))
'*accessing-code*
,(format nil "~A" (access-pair-subbox access-pair)))))
(DEFUN ROW-ENTRY? (X)
(OR (SYMBOLP X)
;(NAME-PAIR? X)
(LABEL-PAIR? X)))
(DEFUN ROW-ENTRY-ELEMENT (ENTRY)
(COND ((LABEL-PAIR? ENTRY) (LABEL-PAIR-ELEMENT ENTRY))
;((NAME-PAIR? ENTRY) (NAME-PAIR-ELEMENT ENTRY))
(T ENTRY)))
(DEFUN ROW-ENTRY-LABEL (ENTRY)
(COND ((LABEL-PAIR? ENTRY) (LABEL-PAIR-LABEL ENTRY))
(T ':NO-LABEL)))
;(DEFUN ROW-ENTRY-NAME (ENTRY)
; (COND ((NAME-PAIR? ENTRY) (NAME-PAIR-NAME ENTRY))
; (T ':NO-NAME)))
(EVAL-WHEN (LOAD)
#-LMITI
(SET-SYNTAX-FROM-CHAR *STRT-ROW-CODE* #/( *BOXER-READTABLE*)
#-LMITI
(SET-SYNTAX-FROM-CHAR *STOP-ROW-CODE* #/) *BOXER-READTABLE*)
#+LMITI
(MULTIPLE-VALUE-BIND (FUN TERM-P)
(GET-MACRO-CHARACTER #/()
(SET-MACRO-CHARACTER *STRT-ROW-CODE* FUN TERM-P *BOXER-READTABLE*))
#+LMITI
(MULTIPLE-VALUE-BIND (FUN TERM-P)
(GET-MACRO-CHARACTER #/))
(SET-MACRO-CHARACTER *STOP-ROW-CODE* FUN TERM-P *BOXER-READTABLE*))
(SET-SYNTAX-FROM-DESCRIPTION *QUOTE-CODE* 'SI:SLASH *BOXER-READTABLE*)
(SET-SYNTAX-MACRO-CHAR *STRT-BOX-CODE*
'BOXER-STRT-BOX-READER-MACRO
*BOXER-READTABLE*)
(SET-SYNTAX-MACRO-CHAR *STOP-BOX-CODE*
'BOXER-STOP-BOX-READER-MACRO
*BOXER-READTABLE*)
(SET-SYNTAX-MACRO-CHAR *INPUTS-CODE*
'BOXER-INPUTS-CHA-READER-MACRO
*BOXER-READTABLE*)
(SET-SYNTAX-MACRO-CHAR *LABELLING-CODE*
'BOXER-LABELLING-CHA-READER-MACRO
*BOXER-READTABLE*)
(set-syntax-macro-char *accessing-code*
'boxer-access-cha-reader-macro
*boxer-readtable*)
(set-syntax-macro-char #\space
'boxer-EV-row-whitespace-macro
*boxer-readtable*)
(SET-SYNTAX-MACRO-CHAR #/@
'BOXER-READER-UNBOX-MACRO
*BOXER-READTABLE*)
(SET-SYNTAX-MACRO-CHAR #/!
'BOXER-READER-EVAL-MACRO
*BOXER-READTABLE*)
;PEOPLE comments.
(SET-SYNTAX-MACRO-CHAR #/;
'BOXER-COMMENT-CHA-READER-MACRO
*BOXER-READTABLE*)
;Returned values.
(SET-SYNTAX-MACRO-CHAR #/|
'BOXER-RETURNED-VALUE-CHA-READER-MACRO
*BOXER-READTABLE*)
(SET-SYNTAX-FROM-DESCRIPTION #/` 'SI:ALPHABETIC *BOXER-READTABLE*)
(SET-SYNTAX-FROM-DESCRIPTION #/, 'SI:ALPHABETIC *BOXER-READTABLE*)
;(SET-SYNTAX-FROM-DESCRIPTION #/( 'SI:ALPHABETIC *BOXER-READTABLE*)
;(SET-SYNTAX-FROM-DESCRIPTION #/) 'SI:ALPHABETIC *BOXER-READTABLE*)
(SET-SYNTAX-FROM-DESCRIPTION #/# 'SI:ALPHABETIC *BOXER-READTABLE*)
(SET-SYNTAX-FROM-DESCRIPTION #// 'SI:ALPHABETIC *BOXER-READTABLE*)
(SET-SYNTAX-FROM-DESCRIPTION #/' 'SI:ALPHABETIC *BOXER-READTABLE*)
;Screws floating point, but what the hell. Otherwise we have to
;avoid "." between delimiters. Currently, we use the GJC fix
;of looking at the atoms and seeing if they LOOK like flonums...
(SET-SYNTAX-FROM-DESCRIPTION #/. 'SI:ALPHABETIC *BOXER-READTABLE*)
)
(defun get-sensible-last-thing-from (list-so-far)
(cond ((eq list-so-far ':toplevel) (ferror "You need a name for this object!"))
((null list-so-far) '(()))
(t (let ((last-thing (last list-so-far)))
(if (spaces? (car last-thing))
(get-sensible-last-thing-from (nbutlast list-so-far))
last-thing)))))
;; note: we can't convert single element boxes with numbers to numbers here because of CHANGE
(DEFUN BOXER-STRT-BOX-READER-MACRO (IGNORE STREAM)
(VALUES (FUNCALL STREAM ':TYI-A-BOX) NIL NIL))
(DEFUN BOXER-STOP-BOX-READER-MACRO (IGNORE IGNORE)
(FERROR "Boxer-Stream out of synch, Boxer-Read should never see a *Stop-Box-Code*"))
(DEFUN BOXER-LABELLING-CHA-READER-MACRO (LIST-SO-FAR STREAM)
(LET ((NEXT-NONBLANK-CHAR (TYIPEEK T STREAM *STOP-ROW-CODE*)))
(IF (EQ LIST-SO-FAR ':TOPLEVEL)
(VALUES (NCONS (MAKE-LABEL-PAIR NIL
(IF (= NEXT-NONBLANK-CHAR *STOP-ROW-CODE*)
':NO-ELEMENT
(READ STREAM ':NO-ELEMENT))))
NIL T)
(LET* ((LAST (get-sensible-last-thing-from list-so-far))
(LAST-ELEMENT (CAR LAST)))
(RPLACA LAST (MAKE-LABEL-PAIR LAST-ELEMENT
(IF (= NEXT-NONBLANK-CHAR *STOP-ROW-CODE*)
':NO-ELEMENT
(READ STREAM ':NO-ELEMENT))))
(VALUES LIST-SO-FAR NIL T)))))
(DEFUN BOXER-INPUTS-CHA-READER-MACRO (LIST-SO-FAR IGNORE)
(VALUES (APPEND LIST-SO-FAR (NCONS 'BU:INPUTS)) NIL T))
(defun boxer-access-cha-reader-macro (list-so-far stream)
(let* ((last (get-sensible-last-thing-from list-so-far))(last-element (car last))
(next-nonblank-char (tyipeek t stream *stop-row-code*)))
(if (not (numberp last-element))
(rplaca last (make-access-pair last-element (if (= next-nonblank-char *stop-row-code*)
':no-element
(read stream ':no-element))))
(rplaca last (+ last-element
(if (= next-nonblank-char *stop-row-code*) 0.
(let ((no (read stream ':no-element)))
(if (zerop no) 0.
(* no
(// 1.0 (expt 10
(1+ (fix (// (log no) (log 10)))))))))))))
(values list-so-far nil t)))
(DEFUN BOXER-EV-ROW-WHITESPACE-MACRO (LIST-SO-FAR STREAM)
STREAM ; the variable was bound but never used...
(COND ((EQ LIST-SO-FAR ':TOPLEVEL)(VALUES LIST-SO-FAR NIL T))
(T (LET ((LAST-EL (CAR (LAST LIST-SO-FAR)))(RESULT))
(COND ((SPACES? LAST-EL)(RPLACD LAST-EL (1+ (GET-SPACES LAST-EL)))
(VALUES LIST-SO-FAR NIL T))
(T (SETQ RESULT (NCONC LIST-SO-FAR (LIST (CONS *SPACING-INFO-SYMBOL* 1))))
(VALUES RESULT NIL T)))))))
;;; Excls and Atsigns...
(DEFUN BOXER-READER-EVAL-MACRO (LIST-SO-FAR STREAM)
(IF (EQ LIST-SO-FAR :TOPLEVEL)
(VALUES (LIST (MAKE-EVAL-IT-TOKEN (READ STREAM #\SPACE))) NIL T)
(VALUES (NCONC LIST-SO-FAR
(LIST (MAKE-EVAL-IT-TOKEN (READ STREAM #\SPACE))))
NIL T)))
(DEFUN BOXER-READER-UNBOX-MACRO (LIST-SO-FAR STREAM)
(IF (EQ LIST-SO-FAR :TOPLEVEL)
(VALUES (LIST (MAKE-UNBOX-TOKEN *UNBOX-MARKER* (READ STREAM #\SPACE))) NIL T)
(VALUES (NCONC LIST-SO-FAR
(LIST (MAKE-UNBOX-TOKEN *UNBOX-MARKER*
(READ STREAM #\SPACE))))
NIL T)))
(COMMENT ;;READER needs to save ALL text. This may change with virtual copy....
;; empty out spaces looking for *STOP-ROW-CODE*, if we encounter an object call READ so we
;; can :TYI-A-BOX if we have to...
(DEFUN BOXER-COMMENT-CHA-READER-MACRO (LIST-SO-FAR STREAM)
(DO ((INPUT (FUNCALL STREAM ':TYIPEEK) (FUNCALL STREAM ':TYIPEEK)))
((OR (EQ INPUT *STOP-ROW-CODE*) (NULL INPUT))
(VALUES LIST-SO-FAR NIL T))
(IF (CHAR= INPUT *STRT-BOX-CODE*)
(READ STREAM *STOP-ROW-CODE*)
(FUNCALL STREAM ':TYI))))
)
(DEFUN BOXER-RETURNED-VALUE-CHA-READER-MACRO (LIST-SO-FAR IGNORE)
(VALUES (APPEND LIST-SO-FAR (NCONS *VERTICAL-BAR-COMMENT*)) NIL T))
(DEFUN BOXER-COMMENT-CHA-READER-MACRO (LIST-SO-FAR IGNORE)
(VALUES (APPEND LIST-SO-FAR (NCONS *SEMI-COLON-COMMENT*)) NIL T))
(DEFUN BOXER-READ (STREAM EOF-OPTION)
(LET ((PACKAGE PKG-BOXER-USER-PACKAGE))
(BOXER-READ-P2 ;;convert atoms that look like flonums to flonums, since "." is turned off.
(LET ((READTABLE *BOXER-READTABLE*))
(READ STREAM EOF-OPTION)))))
(DEFUN BOXER-READ-P2 (EXP)
(IF (ATOM EXP)
(IF (SYMBOLP EXP)
(LET ((R (ERRSET (READ-FROM-STRING (GET-PNAME EXP)) NIL)))
(IF (NUMBERP (CAR R))
(CAR R)
EXP))
EXP)
(CONS (BOXER-READ-P2 (CAR EXP))
(BOXER-READ-P2 (CDR EXP)))))
(DEFUN NAMED-BOX-P (THING)
(AND (BOX? THING) (NAME-ROW? (TELL THING :NAME-ROW))))
;(defmethod (row :entries-for-pre-box)()
; (let ((firstcut (tell self :uncopied-entries-for-pre-box)))
; (mapcar #'(lambda (entry)(if (box? entry)(translate-box-to-pre-box entry) entry))
; firstcut)))
(defmethod (row :entries-for-pre-box)()
(let* ((result (pre-row-read (make-row-stream self) nil))
(result2 (totally-deblank result)))
(setq cached-entries result2)
(setq cached-elements (mapcar #'row-entry-element cached-entries))
result))
(defvar *boxer-pre-row-reader-on?* nil)
(defvar *boxer-pre-row-build-reader-on?* nil)
(defun pre-row-read (row-stream eof-option &optional (build-reader? nil))
(let ((package pkg-boxer-user-package))
(boxer-read-p2
(let ((readtable *boxer-readtable*)(read-preserve-delimiters t)
(*boxer-pre-row-reader-on?* t)
(*boxer-pre-row-build-reader-on?* build-reader?))
(read row-stream eof-option)))))
(defmethod (row :entries-for-build-pre-box)()
(pre-row-read (make-row-stream self) nil t))
;(defun read-with-spaces (row-stream eof-option)
; (tell row-stream :tyi) ;to get opening paren out of the way
; (prog ((result nil)(space-ctr 0)(next-cha nil))
; (setq *boxer-pre-row-reader-on?* t)
; (setq result (append result (read row-stream eof-option)))
; (setq *boxer-pre-row-reader-on?* nil)(return result)))
; tag1
; (setq next-cha (tell row-stream :tyipeek))
; (cond ((and (neq next-cha #\space)(not (= space-ctr 0)))
; (setq result (append result (list `( ,space-ctr))))
; (setq space-ctr 0)
; (go tag1))
; ((eq next-cha #\})
; (tell row-stream :tyi)(setq result (append result eof-option))
; (return result)))
; tag2
; (if (eq next-cha #\space)
; (progn (setq space-ctr (1+ space-ctr))
; (tell row-stream :tyi)(go tag1)))
; (setq result (append result (list (read row-stream eof-option))))
; (go tag1)))
(DEFMETHOD (ROW :CACHE-READ-RESULT) ()
(SETQ CACHED-ITEMS (BOXER-READ (MAKE-ROW-STREAM SELF) nil)
CACHED-ENTRIES (PARSE-LIST-FOR-EVAL CACHED-ITEMS)
CACHED-ELEMENTS (MAPCAR #'ROW-ENTRY-ELEMENT CACHED-ENTRIES)
CACHED? T))
(DEFMETHOD (ROW :ENTRIES) ()
(UNLESS CACHED? (TELL SELF :CACHE-READ-RESULT))
CACHED-ENTRIES)
(DEFMETHOD (ROW :ELEMENTS) ()
(UNLESS CACHED? (TELL SELF :CACHE-READ-RESULT))
CACHED-ELEMENTS)
(DEFMETHOD (ROW :ITEMS) ()
(UNLESS CACHED? (TELL SELF :CACHE-READ-RESULT))
CACHED-ITEMS)
(DEFMETHOD (ROW :EVROW) ()
(UNLESS CACHED? (TELL SELF :CACHE-READ-RESULT))
CACHED-ITEMS)
#+SYMBOLICS(COMPILER:MAKE-MESSAGE-OBSOLETE :EVROW "Use the :ITEMS message instead")
(DEFMETHOD (ROW :LABELS) ()
(MAPCAR #'ROW-ENTRY-LABEL (TELL SELF :ENTRIES)))
;(DEFMETHOD (ROW :NAMES) ()
; (MAPCAR #'ROW-ENTRY-NAME (TELL SELF :ENTRIES)))
(DEFMETHOD (ROW :TEXT-STRING) ()
(LET ((STREAM (MAKE-ROW-STREAM SELF)))
(TYI STREAM)
(LET ((STRING (READLINE STREAM)))
(NSUBSTRING STRING 0 (1- (STRING-LENGTH STRING))))))
(DEFMETHOD (BOX :TEXT-STRING) ()
(LET ((ROWS (BOX-ROWS SELF)))
(DO ((ROWS ROWS (CDR ROWS))
(STUFF ""))
((NULL ROWS) (SUBSTRING STUFF 1))
(SETQ STUFF (STRING-APPEND STUFF
#\CR
(TELL (CAR ROWS) :TEXT-STRING))))))
(DEFUN MAKE-BOX-FROM-STRING (STRING)
"make a box from a string. carriage returns start new rows. this is the inverse function
to the :TEXT-STRING method of boxes. "
(MAKE-BOX
(LOOP WITH START = 0
FOR INDEX FROM 0 TO (1- (STRING-LENGTH STRING))
FOR CHA = (AREF STRING INDEX)
WHEN (OR (CHAR= CHA #\CR) (CHAR= CHA #\LINE))
COLLECT (NCONS (NSUBSTRING STRING START INDEX)) INTO ROWS
WHEN (OR (CHAR= CHA #\CR) (CHAR= CHA #\LINE))
DO (SETQ START (1+ INDEX))
FINALLY
(RETURN (APPEND ROWS (NCONS (NCONS (NSUBSTRING STRING START INDEX))))))))
;;;;MAKE-mumble functions
;;Use these functions to make chas rows and boxes.
(DEFUN MAKE-ROW (STUFF &OPTIONAL (COPY? T))
(COND ((ROW? STUFF)
STUFF)
(T
(LET ((ROW-STREAM (MAKE-ROW-STREAM `(:ROW . ,STUFF)))
(NEW-ROW (MAKE-INITIALIZED-ROW)))
(TELL NEW-ROW :SET-CONTENTS-FROM-STREAM ROW-STREAM COPY?)
NEW-ROW))))
;(DEFUN MAKE-NAME-AND-INPUT-ROW (STUFF &OPTIONAL (CACHED-NAME NIL))
; (COND ((ROW? STUFF)
; STUFF)
; (T
; (LET ((ROW-STREAM (MAKE-ROW-STREAM `(:ROW . ,STUFF)))
; (NEW-ROW (MAKE-INSTANCE 'NAME-AND-INPUT-ROW ':CACHED-NAME CACHED-NAME)))
; (TELL NEW-ROW :SET-CONTENTS-FROM-STREAM ROW-STREAM NIL)
; NEW-ROW))))
(DEFUN MAKE-BOX (STUFF &OPTIONAL (TYPE ':DATA-BOX) NAME)
(COND ((BOX? STUFF)
(TELL STUFF :SET-TYPE TYPE) ;Should it copy instead? --Leigh.
(UNLESS (NULL NAME)
(TELL STUFF :SET-NAME (MAKE-NAME-ROW `(,NAME))))
STUFF)
(T
(LET ((ROWS (OR (MAPCAR 'MAKE-ROW STUFF) `(,(MAKE-ROW ()))))
(BOX (MAKE-INITIALIZED-BOX ':TYPE TYPE)))
(TELL BOX :SET-FIRST-INFERIOR-ROW (CAR ROWS))
(TELL (CAR ROWS) :SET-SUPERIOR-BOX BOX)
(DOLIST (ROW (CDR ROWS))
(TELL BOX :APPEND-ROW ROW))
(UNLESS (NULL NAME)
(TELL BOX :SET-NAME (MAKE-NAME-ROW `(,NAME))))
BOX))))
(defun make-row-from-pre-row (pre-row)
(let ((row-stream (make-row-stream `(:pre-row . ,pre-row)))
(new-row (make-initialized-row)))
(tell new-row :set-contents-from-stream row-stream t)
new-row))
(DEFUN BOX-ROWS (BOX)
(TELL BOX :ROWS))
(DEFUN ROW-ELEMENTS (ROW)
(TELL ROW :ELEMENTS))
(DEFUN ROW-LABELS (ROW)
(TELL ROW :LABELS))
;(DEFUN ROW-NAMES (ROW)
; (TELL ROW :NAMES))
(DEFUN ROW-ENTRIES (ROW)
(TELL ROW :ENTRIES))
;;;boxtop utilities..
;
;(DEFMETHOD (NAME-AND-INPUT-ROW :CACHED-NAME) ()
; CACHED-NAME)
;
;(DEFMETHOD (NAME-AND-INPUT-ROW :INSERT-CHA-AT-CHA-NO) (CHA CHA-NO)
; (CHAS-ARRAY-INSERT-CHA CHAS-ARRAY CHA-NO (IF (BOX? CHA) CHA (DPB *FONT-NUMBER-FOR-NAMING*
; %%BOXER-FONT-NO-FIELD
; CHA)))
; (WHEN (BOX? CHA)
; (PUSH CHA BOXES)
; (TELL CHA :SET-SUPERIOR-ROW SELF))
; (TELL SELF :MODIFIED))
;
;(DEFMETHOD (NAME-AND-INPUT-ROW :UPDATE-BINDINGS) ()
; (LET ((NEW-NAME (GET-BOX-NAME SELF))
; (ENVIRONMENT (TELL SUPERIOR-BOX :SUPERIOR-BOX)))
; (WHEN (NEQ NEW-NAME CACHED-NAME)
; (UNLESS (NULL CACHED-NAME)
; (TELL ENVIRONMENT :REMOVE-STATIC-VARIABLE CACHED-NAME))
; (SETQ CACHED-NAME NEW-NAME))
; (UNLESS (AND (STRINGP NEW-NAME) (STRING-EQUAL NEW-NAME ""))
; (TELL ENVIRONMENT :ADD-STATIC-VARIABLE-PAIR NEW-NAME SUPERIOR-BOX))))
;;; Name Tab utilities
(DEFMETHOD (NAME-ROW :CACHED-NAME) ()
CACHED-NAME)
(DEFMETHOD (NAME-ROW :INSERT-CHA-AT-CHA-NO) (CHA CHA-NO)
"Gives the characters in the naming area a different font. "
(IF (BOX? CHA)
(FERROR "An attempt was made to insert the box, ~S, into the row ~S" CHA SELF)
(CHAS-ARRAY-INSERT-CHA CHAS-ARRAY CHA-NO (DPB *FONT-NUMBER-FOR-NAMING*
%%BOXER-FONT-NO-FIELD
CHA)))
(TELL SELF :MODIFIED))
(DEFMETHOD (NAME-ROW :INSERT-ROW-CHAS-AT-CHA-NO) (ROW CHA-NO)
(LET ((ROW-CHAS-ARRAY (TELL ROW :CHAS-ARRAY))
(NEW-BOXES (TELL ROW :BOXES-IN-ROW)))
(IF (NOT-NULL NEW-BOXES)
(FERROR "An attempt was made to insert the boxes, ~S, into the row ~S" NEW-BOXES SELF)
(CHAS-ARRAY-MOVE-CHAS ROW-CHAS-ARRAY 0
CHAS-ARRAY CHA-NO
(CHAS-ARRAY-ACTIVE-LENGTH ROW-CHAS-ARRAY)
SELF)))
(TELL SELF :MODIFIED))
(DEFMETHOD (NAME-ROW :UPDATE-BINDINGS) (&OPTIONAL (FORCE-RENAME? NIL))
(LET ((NEW-NAME (GET-BOX-NAME SELF))
(ENVIRONMENT (TELL SUPERIOR-BOX :SUPERIOR-BOX)))
(COND ((AND (OR FORCE-RENAME? (NEQ NEW-NAME CACHED-NAME)) (NOT (NULL NEW-NAME)))
;; if the name has changed, then remove the old name from the environment
(UNLESS (OR (NULL CACHED-NAME)
(NEQ SUPERIOR-BOX
(cdr (TELL ENVIRONMENT
:LOOKUP-STATIC-VARIABLE-IN-BOX-ONLY CACHED-NAME))))
(TELL ENVIRONMENT :REMOVE-STATIC-VARIABLE CACHED-NAME))
(SETQ CACHED-NAME NEW-NAME)
(TELL ENVIRONMENT :ADD-STATIC-VARIABLE-PAIR NEW-NAME SUPERIOR-BOX))
((NEQ NEW-NAME CACHED-NAME)
(UNLESS (OR (NULL CACHED-NAME)
(NEQ SUPERIOR-BOX
(cdr (TELL ENVIRONMENT
:LOOKUP-STATIC-VARIABLE-IN-BOX-ONLY CACHED-NAME))))
(TELL ENVIRONMENT :REMOVE-STATIC-VARIABLE CACHED-NAME))
(SETQ CACHED-NAME NEW-NAME)))))
;;;;COPYing
(DEFVAR .LINK-TARGET-ALIST. NIL
"An association list of ported-to boxes and their copies. ")
(DEFVAR .PORT-COPY-LIST. NIL
"A list of port copies which may want to have their destination changed at the end of a
higher level copy operation. ")
(DEFUN COPY-TOP-LEVEL-BOX (BOX)
(LET ((RETURN-BOX (COPY-BOX BOX NIL)))
(DOLIST (PORT .PORT-COPY-LIST.)
(LET ((TARGET-PAIR (ASSQ (TELL PORT :PORTS) .LINK-TARGET-ALIST.)))
(WHEN (NOT-NULL TARGET-PAIR)
(TELL PORT :SET-PORT-TO-BOX (CDR TARGET-PAIR)))))
(SETQ .LINK-TARGET-ALIST. NIL
.PORT-COPY-LIST. NIL)
RETURN-BOX))
(DEFUN COPY-BOX (BOX &OPTIONAL (WITH-NAME? T))
(LET ((NEW-BOX (TELL BOX :COPY)))
(WHEN (NULL WITH-NAME?))
(TELL NEW-BOX :SET-NAME NIL)
NEW-BOX))
(DEFUN COPY-ROW (ROW)
(TELL ROW :COPY))
(DEFMETHOD (BOX :COPY) ()
(LET ((NEW-BOX (MAKE-INITIALIZED-BOX))
(BOX-STREAM (MAKE-BOX-STREAM SELF)))
(TELL NEW-BOX :SET-CONTENTS-FROM-STREAM BOX-STREAM T)
(unless (null local-library)
(let ((new-ll (tell local-library :copy)))
(tell new-box :set-local-library new-ll)
(tell new-ll :export-all-variables)
(tell new-box :add-static-variable-pair *exporting-box-marker* new-ll)))
(WHEN (NOT-NULL PORTS)
(PUSH (CONS SELF NEW-BOX) .LINK-TARGET-ALIST.))
NEW-BOX))
(DEFMETHOD (PORT-BOX :COPY) ()
(LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
(TELL NEW-BOX :SET-TYPE (TELL SELF :TYPE))
(TELL NEW-BOX :SET-DISPLAY-STYLE-LIST DISPLAY-STYLE-LIST)
(TELL NEW-BOX :SET-PORT-TO-BOX PORTS)
(unless (null (tell self :name-row))
(tell new-box :set-name (make-name-row `(,(tell self :name)))))
(LET ((TARGET-PAIR (ASSQ PORTS .LINK-TARGET-ALIST.)))
(IF (NULL TARGET-PAIR)
(PUSH NEW-BOX .PORT-COPY-LIST.)
(TELL NEW-BOX :SET-PORT-TO-BOX (CDR TARGET-PAIR))))
NEW-BOX))
(DEFMETHOD (ROW :COPY) ()
(LET ((NEW-ROW (MAKE-INITIALIZED-ROW))
(ROW-STREAM (MAKE-ROW-STREAM SELF)))
(TELL NEW-ROW :SET-CONTENTS-FROM-STREAM ROW-STREAM T)
NEW-ROW))
;;;;BOX-EQUAL
(DEFUN BOX-EQUAL (BOX1 BOX2)
(TELL BOX1 :EQUAL BOX2))
(DEFUN ROW-EQUAL (ROW1 ROW2)
(TELL ROW1 :EQUAL ROW2))
(DEFMETHOD (BOX :EQUAL) (BOX)
(LET ((MY-LENGTH-IN-ROWS (TELL SELF :LENGTH-IN-ROWS))
(HE-LENGTH-IN-ROWS (TELL BOX :LENGTH-IN-ROWS)))
(COND (( MY-LENGTH-IN-ROWS HE-LENGTH-IN-ROWS) NIL)
(T
(DO* ((ROW-NO 0 (+ ROW-NO 1))
(MY-ROW (TELL SELF :ROW-AT-ROW-NO ROW-NO) (TELL SELF :ROW-AT-ROW-NO ROW-NO))
(HE-ROW (TELL BOX :ROW-AT-ROW-NO ROW-NO) (TELL BOX :ROW-AT-ROW-NO ROW-NO)))
((>= ROW-NO MY-LENGTH-IN-ROWS) T)
(OR (TELL MY-ROW :EQUAL HE-ROW)
(RETURN NIL)))))))
(DEFMETHOD (ROW :EQUAL) (ROW)
(LET ((MY-LENGTH-IN-CHAS (TELL SELF :LENGTH-IN-CHAS))
(HE-LENGTH-IN-CHAS (TELL ROW :LENGTH-IN-CHAS)))
(COND (( MY-LENGTH-IN-CHAS HE-LENGTH-IN-CHAS) NIL)
(T
(DO* ((CHA-NO 0 (+ CHA-NO 1))
(MY-CHA (TELL SELF :CHA-AT-CHA-NO CHA-NO) (TELL SELF :CHA-AT-CHA-NO CHA-NO))
(HE-CHA (TELL ROW :CHA-AT-CHA-NO CHA-NO) (TELL ROW :CHA-AT-CHA-NO CHA-NO)))
((>= CHA-NO MY-LENGTH-IN-CHAS) T)
(COND ((AND (BOX? MY-CHA) (BOX? HE-CHA))
(IF (NOT (TELL MY-CHA :EQUAL HE-CHA))
(RETURN NIL)))
((EQ (CHA-CODE MY-CHA) (CHA-CODE HE-CHA))
T)
(T (RETURN NIL))))))))
(COMMENT
;The boxer PRINT function has been removed. Use returned values or something.
;We'll decide what to do sometime later.
(DEFUN BOXER-PRINT (STUFF PLACE)
(FERROR "PRINT is not implemented these days.")
(COND ((BOX? STUFF)
(BOXER-PRINT-BOX STUFF PLACE))
((ROW? STUFF)
(BOXER-PRINT-ROW STUFF PLACE))
((CHA? STUFF)
(BOXER-PRINT-CHA STUFF PLACE))
((STRINGP STUFF)
(BOXER-PRINT-STRING STUFF PLACE))
((SYMBOLP STUFF)
(BOXER-PRINT-SYMBOL STUFF PLACE))
(T
(BOXER-PRINT-RANDOM-THING STUFF PLACE))))
(DEFUN BOXER-PRINT-BOX (BOX PLACE)
(LET ((COPY (COPY-BOX BOX)))
(COND ((EQ PLACE ':CURSOR)
(INSERT-CHA *point* COPY))
((BOX? PLACE)
(IF (NULL (WTELL PLACE :LAST-ROW))
(TELL (MAKE-INITIALIZED-ROW) :APPEND PLACE))
(TELL COPY :APPEND (TELL PLACE :LAST-ROW))))))
(DEFUN BOXER-PRINT-ROW (ROW PLACE)
(LET ((COPY (COPY-ROW ROW)))
(COND ((EQ PLACE ':CURSOR)
(INSERT-ROW *point* COPY))
((BOX? PLACE)
(TELL COPY :APPEND-ROW PLACE))
(T (FERROR "Can't print a row to ~S" place)))))
(DEFUN BOXER-PRINT-CHA (CHA PLACE)
(LET ((COPY (COPY-CHA CHA)))
(COND ((EQ PLACE ':CURSOR)
(INSERT-CHA *point* COPY))
((BOX? PLACE)
(IF (NULL (TELL PLACE :LAST-ROW))
(TELL (MAKE-INITIALIZED-ROW) :APPEND PLACE))
(TELL COPY :APPEND (TELL PLACE :LAST-ROW))))))
(DEFUN BOXER-PRINT-STRING (STRING PLACE)
(WITH-INPUT-FROM-STRING (INSTREAM (MAKE-STRING-WITH-FILL-POINTER STRING))
(DO ((INPUT (TELL INSTREAM :TYI) (TELL INSTREAM :TYI)))
((NULL INPUT))
(BOXER-PRINT-CODE INPUT PLACE))))
(DEFUN BOXER-PRINT-SYMBOL (SYMBOL PLACE)
(BOXER-PRINT-STRING (STRING SYMBOL) PLACE))
(DEFUN BOXER-PRINT-CODE (CODE PLACE)
(COND ((EQ PLACE ':CURSOR)
(IF (= CODE #\RETURN)
(INSERT-RETURN *point*)
(INSERT-CHA *point* (MAKE-CHA CODE))))
((BOX? PLACE)
(IF (NULL (TELL PLACE :LAST-ROW))
(TELL (MAKE-INITIALIZED-ROW) :APPEND PLACE))
(IF (= CODE #\RETURN)
(TELL (MAKE-INITIALIZED-ROW) :APPEND PLACE)
(TELL (MAKE-CHA CODE) :APPEND (TELL PLACE :LAST-ROW))))))
(DEFUN BOXER-PRINT-RANDOM-THING (RANDOM-THING PLACE)
(BOXER-PRINT-STRING (FORMAT NIL "~s" RANDOM-THING) PLACE))
(DEFUN MAKE-STRING-WITH-FILL-POINTER (STUFF)
(LET ((STRING (MAKE-ARRAY '(8.) ':TYPE 'ART-STRING ':LEADER-LIST '(0))))
(COND ((STRINGP STUFF)
(STRING-NCONC STRING STUFF))
(T
(FORMAT STRING "~s" STUFF)))
STRING))
);END OF COMMENTED-OUT PRINT FUNCTION